using System;
using System.Text;
using System.Globalization;
using System.Security.Permissions;
using System.IO;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Text.RegularExpressions;

	/// <summary>
	///		ServerUtility contains internal helper functions.
	/// </summary>
	/// <internalonly/>
	[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
	[System.ComponentModel.Browsable(false)]
	internal sealed class ServerUtility
	{
		private const string SqlStatementSeparatorExpr = @"^\s*GO\s*$";

		private ServerUtility()
		{
			;
		}

		/// <summary>
		/// Base name used for locating resources in the satellite assemblies
		/// </summary>
		internal const string MSCSSharedResourceBaseName = "Microsoft.CommerceServer.Shared.ProjectResources";
		
		/// <summary>
		///		This method is used to take a SQLOLEDB connection string as typically found in the Commerce Server
		///		administration database and remove the "Provider=SQLOLEDB.*" part so that the connection string becomes a
		///		valid ADO.NET SqlClient connection string.
		/// </summary>
		/// <param name="connectionString">The Database connection string.</param>
		/// <param name="cleaned">An output string containing the cleaned connection string</param>
		/// <returns>A boolean indicating whether or not the connection string provided is a valid SqlClient connection string.  The
		///		output parameter is only valid when the returned value is true.</returns>
		/// <remarks>
		///		The connection strings in Admin DB contain Provider info, which works
		///		fine with ADO.NET but not for SQLclient. In this case, there is a need to
		///		remove the "Provider" part of the connection string.
		/// </remarks>
		public static bool CleanSqlClientConnectionString(string connectionString, out string cleaned)
		{
			const string PROVIDER_TOKEN = "Provider";

			cleaned = null;
			try
			{
				OleDbConnectionStringBuilder builder = new OleDbConnectionStringBuilder(connectionString);
				builder.Remove(PROVIDER_TOKEN);
				cleaned = builder.ConnectionString;
				return true;
			}
			catch (ArgumentException)
			{
				// Just swallow the exception if the connection string is not properly formated and return false
				return false;
			}
		}

		/// <summary>
		/// </summary>
		/// <remarks>
		/// </remarks>
		internal static void ExecuteSqlScript(string connectionString, string sqlFileName)
		{
			using (SqlConnection connection = new SqlConnection(connectionString))
			{
				connection.Open();
				ExecuteSqlScript(connection, null, sqlFileName);
			}
		}

		/// <summary>
		/// </summary>
		/// <remarks>
		/// </remarks>
		internal static void ExecuteSqlScript(SqlConnection connection, SqlTransaction transaction, string sqlFileName)
		{
			using(StreamReader fileReader = new StreamReader(sqlFileName))
			{
				string sqlScriptContents = fileReader.ReadToEnd();
				ExecuteSqlScriptFromString(connection, transaction, sqlScriptContents);
			}
		}

		/// <summary>
		/// </summary>
		/// <remarks>
		/// </remarks>
		internal static void ExecuteSqlScriptFromString(string connectionString, string sqlScriptContents)
		{
			using (SqlConnection connection = new SqlConnection(connectionString))
			{
				connection.Open();
				ExecuteSqlScriptFromString(connection, null, sqlScriptContents);
			}
		}

		/// <summary>
		/// </summary>
		/// <remarks>
		/// </remarks>
		internal static void ExecuteSqlScriptFromString(SqlConnection connection, SqlTransaction transaction, string sqlScriptContents)
		{
			using(SqlCommand sqlCommand = new SqlCommand())
			{
				sqlCommand.CommandType = CommandType.Text;
				sqlCommand.CommandTimeout = 0;
				sqlCommand.Connection = connection;
				if (transaction != null)
					sqlCommand.Transaction = transaction;

				string[] expressions = Regex.Split(sqlScriptContents, 
					ServerUtility.SqlStatementSeparatorExpr, 
					RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Multiline);

				foreach (string expression in expressions)
				{
					if(expression == null)
						continue;
					if ( expression.Trim().Length == 0 )
						continue;

					sqlCommand.CommandText = expression;
					sqlCommand.ExecuteNonQuery();
				}
			}
		}

	}
